package com.my.test.exception;

import java.util.HashSet;

public class Start {

    public static void main(String[] args) {
        Start start = new Start();
        start.method1();


    }

    public void method1(){
        method2();
    }

    public void method2(){
        method3();
    }

    public void method3(){
        method4();
    }

    public void method4(){
        method5();
    }

    public void method5(){
        method6();
    }

    public void method6(){
        method7();
    }

    public void method7(){
        method8();
    }

    public void method8(){
        method9();
    }

    public void method9(){
        method10();
    }

    /*public void method10(){
        //System.out.println("hello");
        //int i = 10/0;
        try {
            throw new MyException("异常");

        } catch (Exception e){
            *//*System.out.println(e.getMessage());
            System.out.println(e.toString());*//*
            //e.printStackTrace();
            //System.err.println(getExceptionStack(e));
            try {
                //throw new MyException("异常22222",e);
                Start2 start2 = new Start2();
                start2.method1();

            } catch (Exception e1){
                *//*System.err.println(getExceptionStack(e1));
                e1.printStackTrace();*//*
                //System.out.println(e1.getCause().toString());
                //System.err.println(getExceptionStack(e1));
                //throw new MyException("123",e1);
                e1.printStackTrace();
            }

        }

    }*/

    public void method10(){
        //System.out.println("hello");
        //int i = 10/0;
        try {
            Start2 start2 = new Start2();
            start2.method1();

        } catch (Exception e){
            /*System.out.println(e.getMessage());
            System.out.println(e.toString());*/
            //e.printStackTrace();
            //System.err.println(getExceptionStack(e));
            //throw new MyException("异常22222",e);

            try {
                throw new MyException("异常22222",e);
                /*Start2 start2 = new Start2();
                start2.method1();*/

            } catch (Exception e1){
                //System.err.println(getExceptionStack(e1));
                //e1.printStackTrace();
                //System.out.println(e1.getCause().toString());
                //System.err.println(getExceptionStack(e1,new HashSet<String>()));
                System.err.println(getExceptionStack(e1,new HashSet<String>(),0));
                //throw new MyException("123",e1);
                //e1.printStackTrace();
                //throw new MyException("1");
            }

        }

    }

    /*
    * 只能获取单层异常信息 无法获取caused by
    * */
    public String getExceptionStack1(Exception e){

        StackTraceElement[] stackTraceElements = e.getStackTrace();
        String prefix = "Exception in thread "+"\""+Thread.currentThread().getName()+"\" ";
        String result = prefix+e.toString() + "\n";
        int lenth = stackTraceElements.length - 1;
        for (int i = 0;i<=lenth;i++){
            result = result + "\tat "+stackTraceElements[i].getClassName()+".";
            result = result + stackTraceElements[i].getMethodName()+"(";
            result = result + stackTraceElements[i].getFileName()+".";
            result = result + stackTraceElements[i].getLineNumber()+")\n";
        }

        return result;
    }

    /*
    * 只能获取单层异常信息 无法获取caused by
    * */
    public String getExceptionStack(Throwable e){

        StackTraceElement[] stackTraceElements = e.getStackTrace();
        String prefix = "Exception in thread "+"\""+Thread.currentThread().getName()+"\" ";
        String result = prefix+e.toString() + "\n";
        int lenth = stackTraceElements.length - 1;
        for (int i = 0;i<=lenth;i++){
            String err = stackTraceElements[i].getClassName()+"."+stackTraceElements[i].getMethodName()+"("+stackTraceElements[i].getFileName()+"."+stackTraceElements[i].getLineNumber()+")";
            result = result + "\tat "+err+"\n";

        }

        return result;
    }

    public String getExceptionStack(Throwable e, HashSet<String> set){

        StackTraceElement[] stackTraceElements = e.getStackTrace();
        String prefix = "Exception in thread "+"\""+Thread.currentThread().getName()+"\" ";
        String result = prefix+e.toString() + "\n";
        int lenth = stackTraceElements.length - 1;
        for (int i = 0;i<=lenth;i++){
            String err = stackTraceElements[i].getClassName()+"."+stackTraceElements[i].getMethodName()+"("+stackTraceElements[i].getFileName()+"."+stackTraceElements[i].getLineNumber()+")";
            if (set.contains(err)){
                continue;
            }
            set.add(err);
            result = result + "\tat "+err+"\n";

        }

        Throwable t = e.getCause();

        String cause = "";
        if (t!=null){
            cause = getExceptionStack(t,set);
        }

        /*t.*/
        return result + cause;
    }


    /*
    * 获取Caused by  参数num要初始化为0
    * */
    public String getExceptionStack(Throwable e, HashSet<String> set,int num){

        StackTraceElement[] stackTraceElements = e.getStackTrace();
        String prefix = "";
        if (num == 0){
            prefix = "Exception in thread "+"\""+Thread.currentThread().getName()+"\" ";
        } else {
            prefix = "Caused by: ";
        }
        String result = prefix+e.toString() + "\n";
        int lenth = stackTraceElements.length - 1;
        for (int i = 0;i<=lenth;i++){
            String err = stackTraceElements[i].getClassName()+"."+stackTraceElements[i].getMethodName()+"("+stackTraceElements[i].getFileName()+"."+stackTraceElements[i].getLineNumber()+")";
            if (set.contains(err)){
                continue;
            }
            set.add(err);
            result = result + "\tat "+err+"\n";

        }

        Throwable t = e.getCause();

        String cause = "";
        if (t!=null){
            num++;
            cause = getExceptionStack(t,set,num);
        }

        return result + cause;
    }

}
